home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / SML⁄NJ 93+ / Documentation / examples / textbooks / four_lectures / interp1.sml < prev    next >
Encoding:
Text File  |  1995-12-30  |  9.5 KB  |  346 lines  |  [TEXT/R*ch]

  1. (* interp1.sml:   Mini ML interpreter, VERSION 1 *)
  2.  
  3. signature INTERPRETER=
  4.    sig
  5.       val interpret: string -> string
  6.       val eval: bool ref
  7.       and tc  : bool ref
  8.    end;
  9.  
  10.                   (* syntax *)
  11.  
  12. signature EXPRESSION =
  13.    sig
  14.       datatype Expression =
  15.          SUMexpr of Expression * Expression   |
  16.          DIFFexpr of Expression * Expression   |
  17.          PRODexpr of Expression * Expression   |
  18.          BOOLexpr of bool   |
  19.          EQexpr of Expression * Expression   |
  20.          CONDexpr of Expression * Expression * Expression   |
  21.          CONSexpr of Expression * Expression   |
  22.          LISTexpr of Expression list   |
  23.          DECLexpr of string * Expression * Expression   |
  24.          RECDECLexpr of string * Expression * Expression   |
  25.          IDENTexpr of string   |
  26.          LAMBDAexpr of string * Expression   |
  27.          APPLexpr of Expression * Expression   |
  28.          NUMBERexpr of int
  29.    end
  30.  
  31.  
  32.               (* parsing *)
  33.  
  34. signature PARSER =
  35.    sig
  36.       structure E: EXPRESSION
  37.  
  38.       exception Lexical of string
  39.       exception Syntax of string
  40.  
  41.       val parse: string -> E.Expression
  42.    end
  43.  
  44.  
  45.                         (* environments *)
  46.  
  47. signature ENVIRONMENT =
  48.    sig
  49.       type 'object Environment
  50.  
  51.       exception Retrieve of string
  52.  
  53.       val emptyEnv: 'object Environment
  54.       val declare: string * 'object * 'object Environment -> 'object Environment
  55.       val retrieve: string * 'object Environment -> 'object
  56.    end
  57.  
  58.                         (* evaluation *)
  59. signature VALUE =
  60.    sig
  61.       type Value
  62.       exception Value
  63.  
  64.       val mkValueNumber: int -> Value
  65.           and unValueNumber: Value -> int
  66.  
  67.       val mkValueBool: bool -> Value
  68.           and unValueBool: Value -> bool
  69.  
  70.       val ValueNil: Value
  71.       val mkValueCons: Value * Value -> Value
  72.           and unValueHead: Value -> Value
  73.           and unValueTail: Value -> Value
  74.  
  75.       val eqValue: Value * Value -> bool
  76.       val printValue: Value -> string
  77.    end
  78.  
  79.  
  80. signature EVALUATOR =
  81.    sig
  82.       structure Exp: EXPRESSION
  83.       structure Val: VALUE
  84.       exception Unimplemented
  85.       val evaluate: Exp.Expression -> Val.Value
  86.    end
  87.  
  88.                   (* type checking *)
  89. signature TYPE =
  90.    sig
  91.       type Type 
  92.   
  93.     (*constructors and decstructors*)
  94.       exception Type
  95.       val mkTypeInt: unit -> Type
  96.           and unTypeInt: Type -> unit
  97.  
  98.       val mkTypeBool: unit -> Type
  99.           and unTypeBool: Type -> unit
  100.  
  101.       val prType: Type->string
  102.    end
  103.  
  104.  
  105.  
  106. signature TYPECHECKER =
  107.    sig
  108.       structure Exp: EXPRESSION
  109.       structure Type: TYPE
  110.       exception NotImplemented of string
  111.       exception TypeError of Exp.Expression * string
  112.       val typecheck: Exp.Expression -> Type.Type
  113.    end;
  114.  
  115.                   (* the interpreter*)
  116.  
  117. functor Interpreter
  118.    (structure Ty: TYPE
  119.     structure Value : VALUE
  120.     structure Parser: PARSER
  121.     structure TyCh: TYPECHECKER
  122.     structure Evaluator:EVALUATOR
  123.       sharing Parser.E = TyCh.Exp = Evaluator.Exp
  124.           and TyCh.Type = Ty
  125.           and Evaluator.Val = Value
  126.    ): INTERPRETER=
  127.  
  128. struct
  129.   val eval= ref true    (* toggle for evaluation *)
  130.   and tc  = ref true    (* toggle for type checking *)
  131.   fun interpret(str)=
  132.     let val abstsyn= Parser.parse str
  133.         val typestr= if !tc then Ty.prType(TyCh.typecheck abstsyn)
  134.                      else "(disabled)"
  135.         val valuestr= if !eval then 
  136.                          Value.printValue(Evaluator.evaluate abstsyn)
  137.                       else "(disabled)"
  138.              
  139.     in  valuestr ^ " : " ^ typestr 
  140.     end
  141.     handle Evaluator.Unimplemented => "Evaluator not fully implemented"
  142.          | TyCh.NotImplemented msg => "Type Checker not fully implemented " ^ msg
  143.          | Value.Value   => "Run-time error"
  144.          | Parser.Syntax msg => "Syntax Error: " ^ msg
  145.          | Parser.Lexical msg=> "Lexical Error: " ^ msg
  146.          | TyCh.TypeError(_,msg)=> "Type Error: " ^ msg
  147. end;
  148.                
  149.                     (* the evaluator *)
  150.  
  151. functor Evaluator
  152.   (structure Expression: EXPRESSION
  153.    structure Value: VALUE):EVALUATOR=
  154.  
  155.    struct
  156.       structure Exp= Expression
  157.       structure Val= Value
  158.       exception Unimplemented
  159.  
  160.       local
  161.          open Expression Value
  162.          fun evaluate exp =
  163.             case exp
  164.               of BOOLexpr b => mkValueBool b
  165.                | NUMBERexpr i => mkValueNumber i
  166.                | SUMexpr(e1, e2) =>
  167.                     let val e1' = evaluate e1
  168.                         val e2' = evaluate e2
  169.                     in
  170.                        mkValueNumber(unValueNumber e1' + unValueNumber e2')
  171.                     end
  172.  
  173.                | DIFFexpr(e1, e2) =>
  174.                     let val e1' = evaluate e1
  175.                         val e2' = evaluate e2
  176.                     in
  177.                        mkValueNumber(unValueNumber e1' - unValueNumber e2')
  178.                     end
  179.  
  180.                | PRODexpr(e1, e2) =>
  181.                     let val e1' = evaluate e1
  182.                         val e2' = evaluate e2
  183.                     in
  184.                        mkValueNumber(unValueNumber e1' * unValueNumber e2')
  185.                     end
  186.  
  187.                | EQexpr _ => raise Unimplemented
  188.                | CONDexpr _ => raise Unimplemented
  189.                | CONSexpr _ => raise Unimplemented
  190.                | LISTexpr _ => raise Unimplemented
  191.                | DECLexpr _ => raise Unimplemented
  192.                | RECDECLexpr _ => raise Unimplemented
  193.                | IDENTexpr _ => raise Unimplemented
  194.                | LAMBDAexpr _ => raise Unimplemented
  195.                | APPLexpr _ => raise Unimplemented
  196.  
  197.       in
  198.          val evaluate = evaluate
  199.       end
  200.    end;
  201.  
  202.                         (* the type checker *)   
  203.  
  204. functor TypeChecker
  205.   (structure Ex: EXPRESSION
  206.    structure Ty: TYPE)=
  207. struct
  208.   structure Exp = Ex
  209.   structure Type = Ty
  210.   exception NotImplemented of string
  211.   exception TypeError of Ex.Expression * string
  212.  
  213.   fun tc (exp: Ex.Expression): Ty.Type =
  214.     case exp of
  215.       Ex.BOOLexpr b => Ty.mkTypeBool()
  216.     | Ex.NUMBERexpr _ => Ty.mkTypeInt()
  217.     | Ex.SUMexpr(e1,e2)  => checkIntBin(e1,e2)
  218.     | Ex.DIFFexpr(e1,e2) => checkIntBin(e1,e2)
  219.     | Ex.PRODexpr(e1,e2) => checkIntBin(e1,e2)
  220.     | Ex.LISTexpr _ => raise NotImplemented "(lists)"
  221.     | Ex.CONSexpr _ => raise NotImplemented "(lists)"
  222.     | Ex.EQexpr _ => raise NotImplemented "(equality)"
  223.     | Ex.CONDexpr _ => raise NotImplemented "(conditional)"
  224.     | Ex.DECLexpr _ => raise NotImplemented "(declaration)"
  225.     | Ex.RECDECLexpr _ => raise NotImplemented "(rec decl)"
  226.     | Ex.IDENTexpr _   => raise NotImplemented "(identifier)"
  227.     | Ex.LAMBDAexpr _  => raise NotImplemented "(function)"
  228.     | Ex.APPLexpr _ => raise NotImplemented    "(application)"
  229.  
  230.        
  231.   and checkIntBin(e1,e2) =
  232.     let val t1 = tc e1
  233.         val _  = Ty.unTypeInt t1
  234.                  handle Ty.Type=> raise TypeError(e1,"expected int")
  235.         val t2 = tc e2
  236.         val _  = Ty.unTypeInt t2
  237.                  handle Ty.Type=> raise TypeError(e2,"expected int")
  238.      in Ty.mkTypeInt()
  239.     end;
  240.  
  241.   val typecheck = tc
  242.  
  243. end; (*TypeChecker*)
  244.  
  245.  
  246.   
  247.                      (* the basics -- nullary functors *)
  248.  
  249. functor Type():TYPE =
  250. struct
  251.   datatype Type = INT
  252.                 | BOOL
  253.  
  254.   exception Type
  255.  
  256.   fun mkTypeInt() = INT
  257.   and unTypeInt(INT)=()
  258.     | unTypeInt(_)= raise Type
  259.  
  260.   fun mkTypeBool() = BOOL
  261.   and unTypeBool(BOOL)=()
  262.     | unTypeBool(_)= raise Type
  263.  
  264.   fun prType INT = "int"
  265.   |   prType BOOL= "bool"
  266. end;
  267.  
  268.  
  269.  
  270. functor Expression(): EXPRESSION =
  271.    struct
  272.       type 'a pair = 'a * 'a
  273.  
  274.       datatype Expression =
  275.          SUMexpr of Expression pair   |
  276.          DIFFexpr of Expression pair   |
  277.          PRODexpr of Expression pair   |
  278.          BOOLexpr of bool   |
  279.          EQexpr of Expression pair   |
  280.          CONDexpr of Expression * Expression * Expression   |
  281.          CONSexpr of Expression pair   |
  282.          LISTexpr of Expression list   |
  283.          DECLexpr of string * Expression * Expression   |
  284.          RECDECLexpr of string * Expression * Expression   |
  285.          IDENTexpr of string   |
  286.          LAMBDAexpr of string * Expression   |
  287.          APPLexpr of Expression * Expression   |
  288.          NUMBERexpr of int
  289.    end;
  290.  
  291. functor Value(): VALUE =
  292.    struct
  293.       type 'a pair = 'a * 'a
  294.  
  295.       datatype Value = NUMBERvalue of int   |
  296.                       BOOLvalue of bool   |
  297.                       NILvalue   |
  298.                       CONSvalue of Value pair
  299.  
  300.       exception Value
  301.  
  302.       val mkValueNumber = NUMBERvalue
  303.       val mkValueBool = BOOLvalue
  304.  
  305.       val ValueNil = NILvalue
  306.       val mkValueCons = CONSvalue
  307.  
  308.       fun unValueNumber(NUMBERvalue(i)) = i   |
  309.           unValueNumber(_) = raise Value
  310.  
  311.       fun unValueBool(BOOLvalue(b)) = b   |
  312.           unValueBool(_) = raise Value
  313.  
  314.       fun unValueHead(CONSvalue(c, _)) = c   |
  315.           unValueHead(_) = raise Value
  316.  
  317.       fun unValueTail(CONSvalue(_, c)) = c   |
  318.           unValueTail(_) = raise Value
  319.  
  320.       fun eqValue(c1, c2) = (c1 = c2)
  321.  
  322.                 (* Pretty-printing *)
  323.         
  324.       fun intToString(i:int)=  (if i<0 then " -" else "")^ natToString (abs i)
  325.       and natToString(n:int)=
  326.           let val d = n div 10 in
  327.             if d = 0 then chr(ord"0" + n)
  328.             else natToString(d)^ chr(ord"0" + (n mod 10))
  329.           end
  330.       fun printValue(NUMBERvalue(i)) = intToString(i)   |
  331.           printValue(BOOLvalue(true)) = "true"   |
  332.           printValue(BOOLvalue(false)) = "false"   |
  333.           printValue(NILvalue) = "[]"   |
  334.           printValue(CONSvalue(cons)) = "[" ^ printValueList(cons) ^ "]"
  335.           and printValueList(hd, NILvalue) = printValue(hd)   |
  336.               printValueList(hd, CONSvalue(tl)) =
  337.                  printValue(hd) ^ ", " ^ printValueList(tl)   |
  338.               printValueList(_) = raise Value
  339.    end;
  340.  
  341.  
  342.  
  343.  
  344. (* use "parser.sml"; *)
  345.  
  346.